Imports System.IO
Imports System.Collections.Generic
Imports System.Collections
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input.Touch
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Media

''' <summary>
''' A uniform grid of tiles with collections of gems and enemies.
''' The level owns the player and controls the game's win and lose
''' conditions as well as scoring.
''' </summary>
Public Class RoomNew
	': IDisposable

	Public maze As Maze
	Public map As Map
	'public Player player;
	Public roomStart As Boolean = False

	'Coordinate system
	Public roomName As String
	Public roomIndex As Integer
	Public roomZ As Integer
	Public roomX As Integer
	Public roomY As Integer

	' Physical structure of the level.
	Private tiles As Tile(,)
	'private Tile[,] tilesMask;

	Private Const pWidth As Integer = 10
	Private Const pHeight As Integer = 3
	Private Const pSize As Integer = 30
	Public Const BOTTOM_BORDER As Integer = 16
	'Bottom border for live energy and message space
	Public Const TOP_BORDER As Integer = 6
	' = (400 pixel - BOTTOM_BORDER % 3 ROWS)
	Public Const LEFT_LIMIT As Integer = -70 - 20
	Public Const RIGHT_LIMIT As Integer = 568 - 10
	Public Const TOP_LIMIT As Integer = -50
    Public Shared BOTTOM_LIMIT As Integer = Game1.CONFIG_SCREEN_HEIGHT - BOTTOM_BORDER - 50
	'
	Public widthInLevel As Integer = 0
	Public heightInLevel As Integer = 0

	Public elements As New List(Of Sprite)()
	'private List<Tile> tilesTemporaney = new List<Tile>();
	'public ArrayList tilesTemporaney = ArrayList.Synchronized(_tilesTemporaney);

	'System.Collections.Concurrent. a = new System.Collections.Concurrent();

	Public tilesTemporaney As New ArrayList()
	'public ArrayList tilesTemporaney;

	' Key locations in the level.        

	Public Function SpritesInRoom() As List(Of Sprite)
		Dim list As New List(Of Sprite)()

		For Each s As Sprite In maze.sprites
			If s.SpriteRoom Is Me Then
				list.Add(s)
			End If
		Next


		If maze.player.SpriteRoom.roomName = Me.roomName Then
			list.Add(maze.player)
		End If

		Return list
	End Function


	Public ReadOnly Property content() As ContentManager
		Get
			Return maze.content
		End Get
	End Property
	#Region "Loading"

	Public Sub New(maze As Maze, filePath As String, roomIndex As Integer)
		Me.maze = maze
		Me.roomIndex = roomIndex

		'tilesTemporaney = ArrayList.Synchronized(_tilesTemporaney);
		'LOAD MXL CONTENT
		'map = content.Load<Map>(filePath);

		'LOAD RES CONTENT
		Dim ax As System.Xml.Serialization.XmlSerializer

		Dim txtReader As Stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(filePath)

		'TextReader txtReader = File.OpenText(filePath);


		'Stream astream = this.GetType().Assembly.GetManifestResourceStream(filePath);
		ax = New System.Xml.Serialization.XmlSerializer(GetType(Map))
		map = DirectCast(ax.Deserialize(txtReader), Map)

			'LoadTilesMask();
		LoadTiles()
	End Sub


	Public Sub LooseShake()
		Dim l As List(Of Tile) = DirectCast(GetTiles(Enumeration.TileType.loose), List(Of Tile))
		For Each item As Loose In l
			item.Shake()
		Next
	End Sub





	Private Sub LoadTiles()
		' Allocate the Tile grid.
		tiles = New Tile(map.rows(0).columns.Length - 1, map.rows.Length - 1) {}
		Dim x As Integer = 0
		Dim y As Integer = 0
		Dim newX As Integer = 0

		For Each r As Row In map.rows
			For ix As Integer = 0 To r.columns.Length - 1
				Dim nextTileType As Enumeration.TileType = Enumeration.TileType.space
				If ix + 1 < r.columns.Length Then
					nextTileType = r.columns(ix + 1).tileType
				End If

				tiles(x, y) = LoadTile(r.columns(ix).tileType, r.columns(ix).state, r.columns(ix).switchButton, r.columns(ix).item, nextTileType, r.columns(ix).timeOpen)
				'tiles[x, y].tileAnimation.fra = maze.player.sprite.frameRate_background;
				Dim rect As New Rectangle(x * CInt(Math.Truncate(Tile.Size.X)), y * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(tiles(x, y).Texture.Width), CInt(tiles(x, y).Texture.Height))
				Dim v As New Vector2(rect.X, rect.Y)

				tiles(x, y).Position = New Position(v, v)
				tiles(x, y).Position.X = v.X
				tiles(x, y).Position.Y = v.Y

				'x+1 for avoid base zero x array, WALL POSITION 0-29
				tiles(x, y).panelInfo = newX + roomIndex

				Select Case r.columns(ix).spriteType
					Case Enumeration.SpriteType.kid
						Dim xPlayer As Integer = (x - 1) * Tile.WIDTH + Player.SPRITE_SIZE_X
						Dim yPlayer As Integer = ((y + 1) * (Tile.HEIGHT)) - Sprite.SPRITE_SIZE_Y + RoomNew.TOP_BORDER
						maze.player = New Player(Me, New Vector2(xPlayer, yPlayer), maze.graphicsDevice, r.columns(ix).spriteEffect)
						Exit Select

					Case Enumeration.SpriteType.guard
						Dim xGuard As Integer = (x - 1) * Tile.WIDTH + Player.SPRITE_SIZE_X
						'int yGuard = (y + 1) * (Tile.HEIGHT - Sprite.PLAYER_STAND_FLOOR_PEN - RoomNew.BOTTOM_BORDER + RoomNew.TOP_BORDER);
						Dim yGuard As Integer = ((y + 1) * (Tile.HEIGHT)) - Sprite.SPRITE_SIZE_Y + RoomNew.TOP_BORDER
						Dim g As New Guard(Me, New Vector2(xGuard, yGuard), maze.graphicsDevice, r.columns(ix).spriteEffect)
						maze.sprites.Add(g)
						Exit Select
					Case Else


						Exit Select
				End Select


				x += 1
				newX += 1
			Next
			x = 0
			y += 1
		Next
	End Sub



	''' <summary>
	''' Creates a new Tile. The other Tile loading methods typically chain to this
	''' method after performing their special logic.
	''' </summary>
	''' <param name="name">
	''' Path to a Tile texture relative to the Content/Tiles directory.
	''' </param>
	''' <param name="collision">
	''' The Tile collision type for the new Tile.
	''' </param>
	''' <returns>The new Tile.</returns>
	Private Function LoadTile(tiletype As Enumeration.TileType) As Tile
		Return New Tile(Me, content, tiletype, Enumeration.StateTile.normal, Enumeration.Items.none, Enumeration.TileType.space)
	End Function

	Private Function LoadTile(tiletype As Enumeration.TileType, state As Enumeration.StateTile, switchButton As Integer, item As Enumeration.Items, nextTileType As Enumeration.TileType, timeOpen As Single) As Tile
		Select Case tiletype
			Case Enumeration.TileType.spikes
				Return New Spikes(Me, content, tiletype, state, nextTileType)
				Exit Select

			Case Enumeration.TileType.pressplate
				Return New PressPlate(Me, content, tiletype, state, switchButton, nextTileType)
				Exit Select

			Case Enumeration.TileType.gate
				Return New Gate(Me, content, tiletype, state, switchButton, nextTileType, _
					timeOpen)
				Exit Select

			Case Enumeration.TileType.loose
				Return New Loose(Me, content, tiletype, state, nextTileType)
				Exit Select

			Case Enumeration.TileType.block
				Return New Block(Me, content, tiletype, state, nextTileType)
				Exit Select
			Case Else

				Return New Tile(Me, content, tiletype, state, item, nextTileType)
		End Select

	End Function

	''' <summary>
	''' Unloads the level content.
	''' </summary>
	Public Sub Dispose()
		content.Unload()
	End Sub

	''' <summary>
	''' Restores the player to the starting point to try the level again.
	''' </summary>
	Public Sub StartNewLife(graphicsDevice As GraphicsDevice)
		'Play Sound presentation
		DirectCast(Maze.dContentRes(PrinceOfPersiaGame.CONFIG_SOUNDS & "presentation".ToUpper()), SoundEffect).Play()
		maze.player.Reset()
		DirectCast(Maze.dContentRes(PrinceOfPersiaGame.CONFIG_SOUNDS & "YouMustRescue".ToUpper()), SoundEffect).Play()

	End Sub

	#End Region

	#Region "Bounds and collision"
	''' <summary>
	''' Gets the collision mode of the Tile at a particular location.
	''' This method handles tiles outside of the levels boundries by making it
	''' impossible to escape past the left or right edges, but allowing things
	''' to jump beyond the top of the level and fall off the bottom.
	''' </summary>
	Public Function GetCollision(x As Integer, y As Integer) As Enumeration.TileCollision
		If x < 0 Then
			If y < 0 Then
				Return maze.LeftRoom(Me).tiles(Width - 1, Height - 1).collision
			Else
				Return maze.LeftRoom(Me).tiles(Width - 1, y).collision
			End If
		End If

		If x >= Width Then
			If y < 0 Then
				Return maze.RightRoom(Me).tiles(0, Height - 1).collision
			Else
				Return maze.RightRoom(Me).tiles(0, y).collision
			End If
		End If

		If y >= Height Then
			Return maze.DownRoom(Me).tiles(x, 0).collision
		End If

		If y < 0 Then
			Return maze.UpRoom(Me).tiles(x, Height - 1).collision
		End If

		Return tiles(x, y).collision
	End Function

	Public Overloads Function [GetType](x As Integer, y As Integer) As Enumeration.TileType
		If x < 0 Then
			If y < 0 Then
				Return maze.LeftRoom(Me).tiles(Width - 1, Height - 1).Type
			Else
				Return maze.LeftRoom(Me).tiles(Width - 1, y).Type
			End If
		End If

		If x >= Width Then
			If y < 0 Then
				Return maze.RightRoom(Me).tiles(0, Height - 1).Type
			Else
				Return maze.RightRoom(Me).tiles(0, y).Type
			End If
		End If

		If y >= Height Then
			Return maze.DownRoom(Me).tiles(x, 0).Type
		End If

		If y < 0 Then
			Return maze.UpRoom(Me).tiles(x, Height - 1).Type
		End If
		Return tiles(x, y).Type
	End Function


	Public Function GetTile(playerPosition As Vector2) As Tile
		Dim x As Integer = CInt(Math.Truncate(Math.Floor(CSng(playerPosition.X) / Tile.WIDTH)))
		Dim y As Integer = CInt(Math.Truncate(Math.Floor((CSng(playerPosition.Y) / Tile.HEIGHT))))
		'int y = (int)Math.Floor(((float)(playerPosition.Y - RoomNew.BOTTOM_BORDER) / Tile.HEIGHT));

		Return GetTile(x, y)
	End Function

	Public Function GetTile(x As Integer, y As Integer) As Tile
		If x < 0 Then
			Return maze.LeftRoom(Me).tiles(Width - 1, y)
		End If

		If x >= Width Then
			Return maze.RightRoom(Me).tiles(0, y)
		End If

		If y >= Height Then
			Return maze.DownRoom(Me).tiles(x, 0)
		End If

		If y < 0 Then
			Return maze.UpRoom(Me).tiles(x, Height - 1)
		End If
		Return tiles(x, y)
	End Function

	Public Function GetTiles(tileType As Enumeration.TileType) As List(Of Tile)
		Dim list As New List(Of Tile)()
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				If tileType = tiles(x, y).Type Then
					list.Add(tiles(x, y))
				End If
			Next
		Next
		Return list
	End Function



	''' <summary>
	''' Gets the bounding rectangle of a Tile in world space.
	''' </summary>        
	Public Function GetBounds(x As Integer, y As Integer) As Rectangle
		Dim by As Integer = 0
		If y = 0 Then
			by = TOP_BORDER
		Else
			by = (y * Tile.HEIGHT) + TOP_BORDER
		End If

		Return New Rectangle(x * Tile.WIDTH, by, Tile.WIDTH, Tile.HEIGHT)
	End Function



	''' <summary>
	''' Width of level measured in tiles.
	''' </summary>
	Public ReadOnly Property Width() As Integer
		Get
			Return tiles.GetLength(0)
		End Get
	End Property

	''' <summary>
	''' Height of the level measured in tiles.
	''' </summary>
	Public ReadOnly Property Height() As Integer
		Get
			Return tiles.GetLength(1)
		End Get
	End Property

	#End Region

	#Region "Update"

	Public Sub Update(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		'THIS IS FOR NOT UPDATE THE BLOCK ROOM AND SAVE SOME CPU TIME....
		If Me.roomName = "MAP_blockroom.xml" Then
			Return
		End If
		'player.Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation);

        UpdateTilesTemporaney(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)

        UpdateTiles(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
		'maze.LeftRoom(this).UpdateTilesLeft(gameTime, keyboardState, gamePadState, touchState, accelState, orientation);

		'maze.UpRoom(this).UpdateTilesUp(gameTime, keyboardState, gamePadState, touchState, accelState, orientation);

        UpdateItems(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)

		'update spritesssss
        'UpdateSprites(gameTime, keyboardState, gamePadState, touchState, accelState, orientation);

	End Sub




	#End Region

	#Region "Draw"

	''' <summary>
	''' Draw everything in the level from background to foreground.
	''' </summary>
	Public Sub Draw(gameTime As GameTime, spriteBatch As SpriteBatch)
		DrawTilesInverseNew(gameTime, spriteBatch)
	End Sub

	''' <summary>
	''' Draw everything in the level from background to foreground.
	''' </summary>
	Public Sub DrawMask(gameTime As GameTime, spriteBatch As SpriteBatch)
		DrawTilesMask(gameTime, spriteBatch)
		DrawTilesBlocks(gameTime, spriteBatch)
	End Sub

	Public Sub DrawSprites(gameTime As GameTime, spriteBatch As SpriteBatch)
		For Each s As Sprite In SpritesInRoom()
			Select Case s.[GetType]().Name
				Case "Guard"
					DirectCast(s, Guard).Draw(gameTime, spriteBatch)
					Exit Select

				Case "Splash"
					DirectCast(s, Splash).Draw(gameTime, spriteBatch)
					Exit Select
				Case Else

					Exit Select
			End Select
		Next

	End Sub


	Private Sub UpdateTilesLeft(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = Width - 1 To Width - 1
				' If there is a visible Tile in that position
				Dim texture As Texture2D = Nothing
				texture = tiles(x, y).Texture
				If texture IsNot Nothing Then
					' Draw it in screen space.
					Dim rect As New Rectangle(-1 * CInt(Math.Truncate(Tile.Size.X)), y * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(texture.Width), CInt(texture.Height))
					Dim position As New Vector2(rect.X, rect.Y)
					tiles(x, y).Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
				End If
			Next
		Next
	End Sub

	Private Sub UpdateTiles(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				tiles(x, y).Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
			Next
		Next
	End Sub

	Private Sub UpdateItems(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				If tiles(x, y).item IsNot Nothing Then
					tiles(x, y).item.Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
				End If
			Next
		Next
	End Sub


	Private Sub UpdateSprites(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		For Each s As Sprite In SpritesInRoom()
            DirectCast(s, Guard).Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
		Next

	End Sub

	Private Sub UpdateTilesTemporaney(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		Try
			'workaroud to thread unsafe...?
			SyncLock tilesTemporaney
				For Each item As Tile In tilesTemporaney
						' Insert your code here.
					item.Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
				Next
			End SyncLock
		Catch ex As Exception
		End Try
	End Sub


	Private Sub UpdateTilesUp(gameTime As GameTime, keyboardState As KeyboardState, gamePadState As GamePadState, touchState As TouchCollection, accelState As AccelerometerState, orientation As DisplayOrientation)
		Dim y As Integer = Height - 1
		For x As Integer = 0 To Width - 1
			' If there is a visible Tile in that position
			Dim texture As Texture2D = Nothing
			texture = tiles(x, y).Texture
			If texture IsNot Nothing Then
				' Draw it in screen space.
				Dim rect As New Rectangle(x * CInt(Math.Truncate(Tile.Size.X)), -1 * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(texture.Width), CInt(texture.Height))
				Dim position As New Vector2(rect.X, rect.Y)
				tiles(x, y).Update(gameTime, keyboardState, gamePadState, touchState, accelState, orientation)
			End If
		Next
	End Sub



	Private Sub DrawTilesLeft(gametime As GameTime, spriteBatch As SpriteBatch)
		' For each Tile position
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = Width - 1 To Width - 1
				' If there is a visible Tile in that position
				Dim texture As Texture2D = Nothing
				texture = tiles(x, y).Texture
				If texture IsNot Nothing Then
					' Draw it in screen space.
					Dim rect As New Rectangle(-1 * CInt(Math.Truncate(Tile.Size.X)), y * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(texture.Width), CInt(texture.Height))
					Dim position As New Vector2(rect.X, rect.Y)
					tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F)
				End If
			Next
		Next

	End Sub

	Private Sub DrawTilesUp(gametime As GameTime, spriteBatch As SpriteBatch)
		' For each Tile position
		Dim y As Integer = Height - 1
		For x As Integer = 0 To Width - 1
			' If there is a visible Tile in that position
			Dim texture As Texture2D = Nothing
			texture = tiles(x, y).Texture
			If texture IsNot Nothing Then
				Dim position As Vector2
				Dim rect As Rectangle
				' Draw it in screen space.
				'if (tiles[x, y].Type == Enumeration.TileType.loose & tiles[x, y].tileState.Value().state == Enumeration.StateTile.loose)
				'{
				'    position.X = tiles[x, y].Position.X;
				'    position.Y = tiles[x, y].Position.Y;
				'}
				'else
				If True Then
					rect = New Rectangle(x * CInt(Math.Truncate(Tile.Size.X)), -1 * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(texture.Width), CInt(texture.Height))
					position = New Vector2(rect.X, rect.Y)
				End If

				tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F)
			End If
		Next

	End Sub


	Private Sub DrawTilesDown(gametime As GameTime, spriteBatch As SpriteBatch)
		' For each Tile position
		Dim y As Integer = 0
		For x As Integer = 0 To Width - 1
			' If there is a visible Tile in that position
			Dim texture As Texture2D = Nothing
			texture = tiles(x, y).Texture
			If texture IsNot Nothing Then
				Dim position As Vector2
				Dim rect As Rectangle
				rect = New Rectangle(x * CInt(Math.Truncate(Tile.Size.X)), (Height - y) * CInt(Math.Truncate(Tile.Size.Y)) - BOTTOM_BORDER, CInt(texture.Width), CInt(texture.Height))
				position = New Vector2(rect.X, rect.Y)

				tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F)
			End If
		Next

	End Sub

	Private Sub DrawTilesBlocks(gametime As GameTime, spriteBatch As SpriteBatch)
		Dim texture As Texture2D = Nothing
		'Rectangle rectangleMask = new Rectangle();

		Dim position As New Vector2(0, 0)
		' For each Tile position
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				If tiles(x, y).Type = Enumeration.TileType.block Then

					If x > 0 AndAlso (tiles(x - 1, y).Type = Enumeration.TileType.space Or tiles(x - 1, y).Type = Enumeration.TileType.floor) Then
						position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y)
						texture = maze.content.Load(Of Texture2D)(PrinceOfPersiaGame.CONFIG_TILES & "Block_left")
						tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, texture)

						'divider
						position = New Vector2(tiles(x, y).Position.X + 16, tiles(x, y).Position.Y + 64)
						texture = maze.content.Load(Of Texture2D)(PrinceOfPersiaGame.CONFIG_TILES & "Block_divider2")

						tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, texture)
					End If

					If tiles(x, y).nextTileType = Enumeration.TileType.block Then
						For s As Integer = 0 To Block.seed_graystone.GetLength(1) - 1
							If Block.seed_graystone(0, s) = tiles(x, y).panelInfo Then
								position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y + 21)
								texture = maze.content.Load(Of Texture2D)(PrinceOfPersiaGame.CONFIG_TILES & "Block_random")
								tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, texture)
							End If
							If Block.seed_left_top(2, s) = DirectCast(tiles(x, y), Block).panelInfo Then
								position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y)
								texture = maze.content.Load(Of Texture2D)(PrinceOfPersiaGame.CONFIG_TILES & "Block_left")
								tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, texture)

								'divider
								position = New Vector2(tiles(x, y).Position.X + 22, tiles(x, y).Position.Y + 64)
								texture = maze.content.Load(Of Texture2D)(PrinceOfPersiaGame.CONFIG_TILES & "Block_divider")

								tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, texture)


							End If



						Next
					End If
				End If
			Next
		Next

		maze.UpRoom(Me).DrawTilesUp(gametime, spriteBatch)
	End Sub

	Private Sub DrawTilesMask(gametime As GameTime, spriteBatch As SpriteBatch)
		Dim rectangleMask As New Rectangle()
		Dim position As New Vector2(0, 0)
		' For each Tile position
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y)

				Select Case tiles(x, y).Type
					Case Enumeration.TileType.posts
						rectangleMask = Tile.MASK_POSTS
						Exit Select
					Case Enumeration.TileType.gate
						position.X = position.X + 50
						rectangleMask = Tile.MASK_DOOR
						Exit Select
					Case Enumeration.TileType.block
						rectangleMask = Tile.MASK_BLOCK
						Exit Select
					Case Else
						position.Y = position.Y + 128
						rectangleMask = Tile.MASK_FLOOR
						Exit Select
				End Select

				tiles(x, y).tileAnimation.DrawTileMask(gametime, spriteBatch, position, SpriteEffects.None, 0.1F, rectangleMask)

				If tiles(x, y).item IsNot Nothing Then
					position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y)
					tiles(x, y).item.itemAnimation.DrawItem(gametime, spriteBatch, position, SpriteEffects.None, 0.1F)
				End If
			Next
		Next

		maze.UpRoom(Me).DrawTilesUp(gametime, spriteBatch)
	End Sub


	Private Sub DrawTilesInverseNew(gametime As GameTime, spriteBatch As SpriteBatch)


		maze.LeftRoom(Me).DrawTilesLeft(gametime, spriteBatch)
		'RoomLeft().DrawTilesLeft(spriteBatch);



		Dim position As New Vector2(0, 0)
		' For each Tile position
		For y As Integer = Height - 1 To 0 Step -1
			For x As Integer = 0 To Width - 1
				Dim texture As Texture2D = Nothing
				texture = tiles(x, y).Texture

				'Rectangle rect = new Rectangle(x * (int)Tile.Size.X, y * (int)Tile.Size.Y - BOTTOM_BORDER, (int)texture.Width, (int)texture.Height);
				'tiles[x, y].Position = new Position(new Vector2(rect.X, rect.Y), new Vector2(rect.X, rect.Y));
				position = New Vector2(tiles(x, y).Position.X, tiles(x, y).Position.Y)



				tiles(x, y).tileAnimation.DrawTile(gametime, spriteBatch, position, SpriteEffects.None, 0.1F)
			Next
		Next
		'RoomUp().DrawTilesUp(spriteBatch);
		maze.DownRoom(Me).DrawTilesDown(gametime, spriteBatch)

		SyncLock tilesTemporaney
			For Each item As Tile In tilesTemporaney
				Dim p As New Vector2(item.Position.X, item.Position.Y)
				item.tileAnimation.DrawTile(gametime, spriteBatch, p, SpriteEffects.None, 0.1F)
			Next
		End SyncLock
	End Sub


	Public Sub SubsTile(coordinate As Vector2, tileType As Enumeration.TileType)
		Dim x As Integer = CInt(Math.Truncate(coordinate.X))
		' (int)Math.Floor((float)position.X / Tile.WIDTH);
		Dim y As Integer = CInt(Math.Truncate(coordinate.Y))
		'(int)Math.Ceiling(((float)(position.Y - RoomNew.BOTTOM_BORDER) / Tile.HEIGHT));
		Dim t As New Tile(Me, content, tileType, Enumeration.StateTile.normal, Enumeration.Items.none, Enumeration.TileType.space)
		Dim p As New Position(tiles(x, y).Position._screenRealSize, tiles(x, y).Position._spriteRealSize)
		p.X = tiles(x, y).Position.X
		p.Y = tiles(x, y).Position.Y
		t.Position = p
		tiles(x, y) = t
		tiles(x, y).tileAnimation.PlayAnimation(t.TileSequence, t.tileState.Value())
	End Sub

	Public Sub SubsTileState(position As Vector2, state As Enumeration.StateTile)
		Dim x As Integer = CInt(Math.Truncate(position.X))
		Dim y As Integer = CInt(Math.Truncate(position.Y))

		tiles(x, y).tileState.Value().state = state
		tiles(x, y).tileAnimation.PlayAnimation(tiles(x, y).TileSequence, tiles(x, y).tileState.Value())
	End Sub


	Public Function getBoundTiles(playerBounds As Rectangle) As Vector4
		Dim leftTile As Integer = CInt(Math.Truncate(Math.Floor(CSng(playerBounds.Left) / Tile.WIDTH)))
		Dim rightTile As Integer = CInt(Math.Truncate(Math.Ceiling((CSng(playerBounds.Right) / Tile.WIDTH)))) - 1
		'tile dal bordo sx dello schermo al bordo dx del rettangolo sprite
		Dim topTile As Integer = CInt(Math.Truncate(Math.Floor(CSng(playerBounds.Top - RoomNew.BOTTOM_BORDER) / Tile.HEIGHT)))
		'tiles from the top screen border
		Dim bottomTile As Integer = CInt(Math.Truncate(Math.Ceiling((CSng(playerBounds.Bottom - RoomNew.BOTTOM_BORDER) / Tile.HEIGHT)))) - 1

		'if (topTile < 0)
		'    topTile = 0;
		If bottomTile > RoomNew.pHeight - 1 Then
			bottomTile = topTile
		End If


		Return New Vector4(leftTile, rightTile, topTile, bottomTile)
	End Function

	Public Function getCenterTile(playerBounds As Rectangle) As Vector2
		Dim leftTile As Integer = CInt(Math.Truncate(Math.Floor(CSng(playerBounds.Center.X) / Tile.WIDTH)))
		Dim topTile As Integer = CInt(Math.Truncate(Math.Floor(CSng(playerBounds.Center.Y - RoomNew.BOTTOM_BORDER) / Tile.HEIGHT)))
		'tiles from the top screen border
		Return New Vector2(leftTile, topTile)
	End Function

	#End Region
End Class
